package manager

import (
	"github.com/tianjigames/fairy/dao"
	"github.com/tianjigames/fairy/pojo"
	"github.com/tianjigames/fairy/util"
	"github.com/topfreegames/pitaya/logger"
	"strings"
	"sync"
	"time"
)

var (
	PlayerManager *playerManager
	playerOnce sync.Once
)


type playerManager struct {
	BaseManager
}

func NewPlayerManager() *playerManager {
	playerOnce.Do(func() {
		PlayerManager = &playerManager{}
	})
	return PlayerManager
}

func (p *playerManager) CreateLocalAccount(username,channelId,password,macid,deviceModel,appId string) (*pojo.AccountData,error) {
	accountId,err := dao.GuidGeneratorDao.GenGuid(int(pojo.GuidTypeAccount))
	if err != nil {
		logger.Log.Errorf("CreateLocalAccount failed,error:%s",err.Error())
		return nil,err
	}

	accountData := &pojo.AccountData{
		AccountId:      accountId,
		ChannelId:      channelId,
		Username:       username,
		AppId:          appId,
		Password:       password,
		Macid:          macid,
		AllPlayerGuids: "",
		CreateTime:     time.Now(),
		ActiveCode:     "",
		DeviceModel:    deviceModel,
	}

	err = dao.AccountDataDao.Add(accountData)
	if err != nil {
		logger.Log.Errorf("CreateLocalAccount failed,error:%s",err.Error())
		return nil,err
	}

	return accountData,nil
}

func (p *playerManager) ListPlayerData(accountData *pojo.AccountData,checkServerId bool) ([]*pojo.PlayerData,error) {
	if accountData == nil {
		return nil,nil
	}

	logger.Log.Infof("ListPlayerData accountId=%d,worldId=%d",accountData.AccountId,accountData.WorldId)
	if len(accountData.AllPlayerGuids) == 0 {
		return nil,nil
	}


	playerDataSlice := make([]*pojo.PlayerData,0)
	allGuids := strings.Split(accountData.AllPlayerGuids,",")
	hasBadGuid := false
	for _,str := range allGuids {
		if len(str) == 0{
			continue
		}

		guid := util.CastLong(str)
		if guid <= 0 {
			continue
		}

		playData,err := dao.PlayerDataDao.GetPlayerDataByGuid(guid)
		if err != nil {
			logger.Log.Errorf("ListPlayerData failed,guid=%d,error:%s",guid,err.Error())
			return nil,err
		}

		if playData == nil {
			hasBadGuid = true
			logger.Log.Errorf("ListPlayerData accountId=%d,guid=%d hasBadGuid",accountData.AccountId,guid)
			accountData.CutPlayerGuid(guid)
			continue
		}


		if playData.Status == pojo.RoleStateDelete || playData.GetStatus() == pojo.OptDelete {
			continue
		}

		if checkServerId && accountData.WorldId != 0 && accountData.WorldId != playData.WorldId {
			continue
		}

		playerDataSlice = append(playerDataSlice,playData)
	}

	if hasBadGuid {
		err := dao.AccountDataDao.Update(accountData)
		if err != nil {
			logger.Log.Errorf("ListPlayerData failed,accountId=%d,error:%s",accountData.AccountId,err.Error())
			return nil,err
		}
	}

	return playerDataSlice,nil
}

func (p *playerManager) CreatePlayer(accountData *pojo.AccountData,roleData *pojo.PlayerData) error {
	err := dao.PlayerDataDao.CreatePlayer(accountData,roleData)
	if err != nil {
		logger.Log.Errorf("CreatePlayer failed,err:%s",err.Error())
		return err
	}

	return nil
}


/**
删除某个角色
 */
func (p *playerManager) DeletePlayer(accountData *pojo.AccountData,playerData *pojo.PlayerData) error {
	err := dao.PlayerDataDao.DeletePlayer(accountData,playerData)
	if err != nil {
		logger.Log.Errorf("DeletePlayer failed,err:%s",err.Error())
		return err
	}

	//todo:删除world服务器上的role

	return nil
}

func (p *playerManager) GetAccountDataByUsernameAndChannelId(username,channelId string) ([]*pojo.AccountData,error) {
	r,err := dao.AccountDataDao.GetAccountDataByUsernameAndChannelId(username,channelId)
	if err != nil {
		logger.Log.Errorf("GetAccountDataByUsernameAndChannelId failed,error:%s",err.Error())
		return nil,err
	}
	return r,nil
}

func (p *playerManager) GetAccountDataByUsernameAndChannelIdAndAppId(username,channelId,appId string) (*pojo.AccountData,error) {
	r,err := dao.AccountDataDao.GetAccountDataByUsernameAndChannelIdAndAppId(username,channelId,appId)
	if err != nil {
		logger.Log.Errorf("GetAccountDataByUsernameAndChannelIdAndAppId failed,error：%s",err.Error())
		return nil,err
	}

	return r,nil
}


func (p *playerManager) RegisterByUserId()  {
	
}


func (p *playerManager) GetAccountDataByAccountId(accountId int64,appId string) (*pojo.AccountData,error) {
	r,err := dao.AccountDataDao.GetAccountDataByAccountId(accountId,appId)
	if err != nil {
		logger.Log.Errorf("[PlayerManager] GetAccountDataByAccountId failed,err:%s",err.Error())
		return nil,err
	}

	return r,nil
}